/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.oai.metadataRepository.repository.collections;

import cz.mzk.oai.metadataRepository.metadata.MarcRecord;
import cz.mzk.oai.metadataRepository.metadata.MultipleDataField;
import cz.mzk.oai.metadataRepository.repository.AlephBase;
import cz.mzk.oai.metadataRepository.repository.RecordAnalyzer;
import cz.mzk.oai.metadataRepository.repository.RecordAnalyzer.BeforeAfterDecision;
import cz.mzk.oai.metadataRepository.repository.Repository;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Martin Rehanek (rehan at mzk.cz)
 */
public class MarcBasedCollectionSelector {

    private RecordAnalyzer analyzer = new RecordAnalyzer();
    private final Repository repository;

    public MarcBasedCollectionSelector(Repository repository) {
        this.repository = repository;
    }

    public MetadataCollection chooseCollectionOrThrowException(MarcRecord record, AlephBase base) throws NoCollectionFoundException {
        MetadataCollection selected = chooseCollection(record, base);
        if (selected == null) {
            throw new NoCollectionFoundException();
        }
        return selected;
    }

    private MetadataCollection chooseCollection(MarcRecord record, AlephBase base) {
        BeforeAfterDecision decision = analyzer.decide1800(record);
        if (base == AlephBase.MZK03) {
            return chooseMzk03Collection(record, decision);
        } else if (base == AlephBase.MZK01) {
            return choosMzk01Collection(record, decision);
        } else {
            return null;
        }
    }

    private MetadataCollection chooseMzk03Collection(MarcRecord record, BeforeAfterDecision decision) {
        //moll
        if (analyzer.isMollMap(record)) {
            return findCollection("mollMaps", decision);
        }
        //schram
        boolean isPortrait = analyzer.isPortrait(record);
        boolean isSchramVeduta = analyzer.isSchramVedutaOrMap(record);
        if (isPortrait && isSchramVeduta) {
            String message = "evaluated as both schramVeduta and schramPortrait. ID:" + record.getId();
            Logger.getLogger(MarcBasedCollectionSelector.class.getName()).log(Level.SEVERE, message);
            //TODO: asi na to vytvorit specialni kolekci.
            return null;
        } else if (isPortrait) {
            return findCollection("schramPortraits", decision);
        } else if (isSchramVeduta) {
            return findCollection("schramVedute", decision);
        }
        //manucripts
        boolean isManuscript = analyzer.isManuscript(record);
        if (isManuscript) {
            return findCollection("manuscripts", decision);
        }
        //oldMaps
        if (analyzer.isOldMap(record)) {
            return findCollection("oldMaps", decision);
        }
        //a co tei? veci z techto kolekci by se totiz presunuly napr. do generalMzk03neco
        //try eod and if no collection chosen, we use default one
        String collectionName = "generalMzk03";
        if (wasDigitizedInEod(record)) {
            collectionName += "_digitized_in_EOD";
        } else if (isReadyForEod(record)) {
            collectionName += "_ready_for_EOD_";
        }
        return findCollection(collectionName, decision);
    }

    private MetadataCollection choosMzk01Collection(MarcRecord record, BeforeAfterDecision decision) {
        String collectionName = "generalMzk01";
        if (wasDigitizedInEod(record)) {
            collectionName += "_digitized_in_EOD_";
        } else if (isReadyForEod(record)) {
            collectionName += "_ready_for_EOD_";
        }
        return findCollection(collectionName, decision);
    }

    private boolean wasDigitizedInEod(MarcRecord record) {
        MultipleDataField datafieldEOD = record.getDatafieldEOD();
        return datafieldEOD.contains('a', "DIG");
    }

    private boolean isReadyForEod(MarcRecord record) {
        MultipleDataField datafieldEOD = record.getDatafieldEOD();
        return datafieldEOD.contains('a', "Y");
    }

    private MetadataCollection findCollection(String prefix, BeforeAfterDecision decision) {
        String collectionName = buildCollectionName(prefix, decision);
        return repository.findCollection(collectionName);
    }

    private String buildCollectionName(String prefix, BeforeAfterDecision decision) {
        switch (decision) {
            case BEFORE:
                return prefix.concat("Before1800");
            case AFTER:
                return prefix.concat("After1800");
            case ERROR:
                return prefix.concat("Error1800");
            default:
                return null;
        }
    }
}
